package com.ptp.handler;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;

import com.alibaba.fastjson.JSON;
import com.ptp.chat.IChat;
import com.ptp.chat.MessageInfo;
import com.ptp.properties.WebSocketProperties;
import io.netty.buffer.ByteBufHolder;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpRequest;
import io.netty.handler.codec.http.websocketx.CloseWebSocketFrame;
import io.netty.handler.codec.http.websocketx.PingWebSocketFrame;
import io.netty.handler.codec.http.websocketx.PongWebSocketFrame;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketServerHandshaker;
import io.netty.handler.codec.http.websocketx.WebSocketServerHandshakerFactory;
/**
 * 
 * @author nnli
 *
 */
public class WebSocketHandler extends ChannelInboundHandlerAdapter implements IChat{

	private Map<String, Channel> channels = new ConcurrentHashMap<String, Channel>();
	
	private String uri;
	
	@Autowired
	private WebSocketProperties webSocketProperties;
	
	private WebSocketServerHandshaker handshaker;
	
	public WebSocketHandler(String uri){
		this.uri = uri;
	}
	
	@Override
	public void channelActive(ChannelHandlerContext ctx) throws Exception {
		System.out.println("通道已经激活");
	}

	@Override
	public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
		httpRequestHandler(ctx,msg);
    	if(msg instanceof CloseWebSocketFrame){
    		handshaker.close(ctx.channel(), ((CloseWebSocketFrame) msg).retain());
    		return;
    	}
    	
    	if(msg instanceof PingWebSocketFrame){
    		ctx.channel().writeAndFlush(new PongWebSocketFrame(((ByteBufHolder) msg).content().retain()));
    		return;
    	}
    	
    	if(msg instanceof TextWebSocketFrame){
    		String text = ((TextWebSocketFrame) msg).text();
    		if(StringUtils.isEmpty(text)){
    			ctx.writeAndFlush(new TextWebSocketFrame("服务端返回:不能发送空消息"));
    		}else{
        		MessageInfo message = JSON.parseObject(text,MessageInfo.class);
        		send(message.getUserId(),message.getRelationId(),channels,message.getMessage().getContent());
    		}
    	}
	}


	@Override
	public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
		//心跳包待处理 TODO
		super.userEventTriggered(ctx, evt);
	}

	@Override
	public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
		Channel channel = ctx.channel();
		channels.keySet().stream().forEach(ele -> {
			ctx.writeAndFlush(new TextWebSocketFrame(channels.get(ele).remoteAddress()+"上线"));
		});
		channels.put(channel.remoteAddress().toString(), channel);
	}

	@Override
	public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
		Channel channel = ctx.channel();
		channels.remove(channel.remoteAddress().toString());
		channels.keySet().stream().forEach(ele -> {
			ctx.writeAndFlush(new TextWebSocketFrame(channels.get(ele).remoteAddress()+"下线"));
		});
	}

	/**
	 * 处理http请求
	 * @param ctx
	 * @param request
	 */
	private void httpRequestHandler(ChannelHandlerContext ctx, Object request){
		if(request instanceof FullHttpRequest){
			if("/websocket".equalsIgnoreCase(((FullHttpRequest) request).uri())){
				WebSocketServerHandshakerFactory factory = new WebSocketServerHandshakerFactory("ws://localhost:8089/websocket",null,false);
				handshaker = factory.newHandshaker((HttpRequest) request);
				if(handshaker == null){
					WebSocketServerHandshakerFactory.sendUnsupportedVersionResponse(ctx.channel());
				}else{
					handshaker.handshake(ctx.channel(), (FullHttpRequest) request);
				}
			}
		}
	}

}
